/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.arg.deploy.webapp.tag.monitor.ctrl;

import com.arg.deploy.bean.Tag;
import com.arg.deploy.bean.TagLookupCatalog;
import com.arg.deploy.common.FileUtil;
import com.arg.deploy.common.GenerateScriptUtil;
import com.arg.deploy.common.ProcessUbuntu;
import com.arg.deploy.common.TextFileReaderUtil;
import com.arg.deploy.core.hibernate.TagCore;
import com.arg.deploy.core.hibernate.TagLookupCatalogCore;
import com.arg.deploy.webapp.add.ctrl.AddTagHotFixCtrl;
import com.arg.deploy.webapp.add.ctrl.AddTagReleaseCtrl;
import com.arg.deploy.webapp.attribute.FileAttribute;
import com.arg.deploy.webapp.common.AlertMessages;
import com.arg.deploy.webapp.common.ComboboxUtil;
import com.arg.deploy.webapp.common.MainPageController;
import static com.arg.deploy.webapp.common.MainPageController.DATE_FORMAT;
import com.arg.deploy.webapp.common.ResourceUtil;
import com.arg.deploy.webapp.common.ValidateManager;
import com.arg.deploy.webapp.common.ValidateUtil;
import com.arg.deploy.webapp.popup.ctrl.PopupCtrl;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zul.Button;
import org.zkoss.zul.Checkbox;
import org.zkoss.zul.Combobox;
import org.zkoss.zul.Datebox;
import org.zkoss.zul.Div;
import org.zkoss.zul.Grid;
import org.zkoss.zul.Label;
import org.zkoss.zul.ListModelList;
import org.zkoss.zul.Radiogroup;
import org.zkoss.zul.RowRenderer;
import org.zkoss.zul.Textbox;
import org.zkoss.zul.Window;

/**
 *
 * @author sorasaks
 */
public class TagMonitorMainCtrl extends MainPageController {

    private static final Logger LOG = Logger.getLogger(TagMonitorMainCtrl.class);
    private static final String FROM_POPUP_TEMPLATE = "/WEB-INF/layouts/defaults/popup/popup.zul";
    private static final String TAG_TYPE_HOTFIX = "2";
    private static final String TAG_TYPE_RELEASE = "1";
    private Checkbox chkAll;
    private Checkbox chkAllError;
    private Combobox cbbTagName;
    private Combobox cbbHeader;
    private Combobox cbbCVSName;
    private Combobox cbbLastedTagName;
    private Datebox startDateBox;
    private Datebox endDateBox;
    private Radiogroup rdoTagType;
    private Radiogroup rdoDateType;
    private Div divError;
    private Grid gridTagNormal;
    private Grid gridErrorTag;
    private Grid gridDiffTag;
    private Button btnRefresh;
    private Button btnGenerate;
    private Button btnRollback;
    private List<String> tagName = new ArrayList<String>();
    private List<String> header = new ArrayList<String>();
    private List<String> cvsName = new ArrayList<String>();
    private List<String> lastedTagName = new ArrayList<String>();
    private TagMonitorNormalMainRenderer normalRender;
    private TagMonitorDiffMainRenderer diffRender;
    private TagMonitorErrorMainRenderer errorRender;
    private Label lbTotalNormal;
    private Label lbTotalDifference;
    private Label lbTotalError;
    private Textbox txtSearch;

    public TagMonitorMainCtrl() {
        super("default.message.title.monitor.release", Boolean.TRUE);
    }

    @Override
    public void doAfterCompose(Component comp) throws Exception {
        super.doAfterCompose(comp); //To change body of generated methods, choose Tools | Templates.
        initialComponent();
        initialCombobox();
        initialRenderer();
        initialEventListener();
    }

    private void initialComponent() {
        startDateBox.setFormat(DATE_FORMAT);
        endDateBox.setFormat(DATE_FORMAT);
        startDateBox.setValue(new Date());
        endDateBox.setValue(new Date());
        startDateBox.setDisabled(true);
        endDateBox.setDisabled(true);
    }

    private void initialEventListener() {
        btnRefresh.addEventListener(Events.ON_CLICK, new MonitorEventListener());
        btnGenerate.addEventListener(Events.ON_CLICK, new GenerateTagScript());
        btnRollback.addEventListener(Events.ON_CLICK, new GenerateRollbackTagScript());
        rdoDateType.addEventListener(Events.ON_CHECK, new DateTypeEventListener());
    }

    private class DateTypeEventListener implements EventListener {

        @Override
        public void onEvent(Event t) throws Exception {
            if (((String) rdoDateType.getSelectedItem().getValue()).equals("2")) {
                startDateBox.setDisabled(false);
                endDateBox.setDisabled(false);
            } else {
                startDateBox.setDisabled(true);
                endDateBox.setDisabled(true);
            }
        }
    }

    private class MonitorEventListener implements EventListener {

        @Override
        public void onEvent(Event t) throws Exception {
            appendSettingFile();
            if (!validate()) {
                return;
            }

            monitor();
        }
    }

    private void initialRenderer() {
        normalRender = new TagMonitorNormalMainRenderer(chkAll, gridTagNormal);
        diffRender = new TagMonitorDiffMainRenderer();
        errorRender = new TagMonitorErrorMainRenderer(chkAllError, gridErrorTag);
        gridTagNormal.setRowRenderer(normalRender);
        gridDiffTag.setRowRenderer(diffRender);
        gridErrorTag.setRowRenderer(errorRender);
    }

    private void monitor() throws UnsupportedEncodingException {
        TagLookupCatalog catalog = null;

        if (((String) rdoTagType.getSelectedItem().getValue()).equals(TAG_TYPE_RELEASE)) {
            catalog = TagLookupCatalogCore.getLookupByName(AddTagReleaseCtrl.TAG_RELEASE);
        } else if (((String) rdoTagType.getSelectedItem().getValue()).equals(TAG_TYPE_HOTFIX)) {
            catalog = TagLookupCatalogCore.getLookupByName(AddTagHotFixCtrl.TAG_HOTFIX);
        }

        if (catalog == null) {
            AlertMessages.alertMessage("ผิดพลาด ::: Tag Type ไม่ถูกต้องกรุณาตรวจสอบ");
            return;
        }

        Date startDate = null;
        Date endDate = null;
        if (((String) rdoDateType.getSelectedItem().getValue()).equals("2")) {
            startDate = startDateBox.getValue();
            endDate = endDateBox.getValue();
        }

        List<Tag> tagList = null;
        if (StringUtils.isEmpty(txtSearch.getValue())) {
            tagList = TagCore.getTag(null, null, catalog, startDate, endDate);
        } else {
            String[] issueArray = txtSearch.getValue().trim().split(",");
            if (issueArray.length > 1) {
                List<String> issueList = new ArrayList<String>();
                List<String> notIssueList = new ArrayList<String>();
                for (String s : issueArray) {
                    if (s.trim().charAt(0) == '-') {
                        notIssueList.add(s.trim().substring(1));
                    } else {
                        issueList.add(s.trim());
                    }
                }
                tagList = TagCore.getTagByListIssue(issueList, notIssueList, null, catalog, startDate, endDate);
            } else {
                if (issueArray[0].charAt(0) == '-') {
                    List<String> notIssueList = new ArrayList<String>();
                    notIssueList.add(issueArray[0].trim().substring(1));
                    tagList = TagCore.getTagByListIssue(null, notIssueList, null, catalog, startDate, endDate);
                } else {
                    tagList = TagCore.getTag(txtSearch.getValue(), null, catalog, startDate, endDate);
                }
            }
        }

        if (tagList == null || tagList.isEmpty()) {
            AlertMessages.alertMessage(ResourceUtil.getLabel("default.alert.message.no.data", locale));
            tagList = new ArrayList<Tag>();
        }

        List<Tag> listNormal = new ArrayList<Tag>();
        List<Tag> listDiff = new ArrayList<Tag>();
        List<Tag> listError = new ArrayList<Tag>();
        List<Tag> listDel = new ArrayList<Tag>();
        List<Tag> listReversionDel = new ArrayList<Tag>();
        List<Integer> listPosDel = new ArrayList<Integer>();
        List<Integer> listPosAdd = new ArrayList<Integer>();
        List<Integer> listPosChangeReversion = new ArrayList<Integer>();

        for (Tag tag : tagList) {

            StringBuilder sb = new StringBuilder();
            sb.append("cvs -d :pserver:").append((String) cbbCVSName.getSelectedItem().getValue()).append("@").append(GenerateScriptUtil.IP_CVS_SERVER_PATH).append(" co ").append(tag.getPath());
            sb.append("\n");
            sb.append("cvs -d :pserver:").append((String) cbbCVSName.getSelectedItem().getValue()).append("@").append(GenerateScriptUtil.IP_CVS_SERVER_PATH).append(" log ").append(tag.getPath());

            LOG.info(":::::::::::::::::::::::: sb = " + sb.toString());

            ProcessUbuntu process = new ProcessUbuntu(cbbHeader.getText(), sb);
            process.process("chmod 777 " + cbbHeader.getText() + "/" + ProcessUbuntu.TEMP_SCRIPT_FILENAME);
            process.process();

            if (!StringUtils.isEmpty(process.getErrorString())) {
                String[] lines = process.getErrorString().split("\n");
                if (lines[0].contains("cvs log: authorization failed: server")) {
                    AlertMessages.alertMessage("ผิดพลาด ::: กรุณา Login CVS");
                    return;
                }
                tag.setDescription(ResourceUtil.getLabel("default.alert.message.invalid.path", locale));
                listError.add(tag);
            } else {
                String[] logTag = process.getOutputString().split("\n");

                Boolean isSuccess = validateTag(logTag, cbbLastedTagName.getText().trim(),
                        tag, 10);

                if (isSuccess) {
                    listNormal.add(tag);
                } else {
                    listError.add(tag);
                }
            }
        }

        for (Tag o1 : listNormal) {
            for (Tag o2 : listNormal) {
                if (o1.getIssue().equalsIgnoreCase(o2.getIssue())
                        && o1.getPath().equalsIgnoreCase(o2.getPath())
                        && !o1.getRevision().equalsIgnoreCase(o2.getRevision())) {

                    boolean isDelDuplicate = false;
                    for (int n : listPosDel) {
                        if (n == listNormal.indexOf(o2)) {
                            isDelDuplicate = true;
                            break;
                        }

                    }

                    for (int n2 : listPosChangeReversion) {
                        if (n2 == listNormal.indexOf(o2)) {
                            isDelDuplicate = true;
                            break;
                        }
                    }

                    String reversion = containReversion(o1.getRevision(), o2.getRevision(), Boolean.FALSE);
                    if (!isDelDuplicate && reversion != null) {
                        o1.setRevision(reversion);
                        listPosChangeReversion.add(listNormal.indexOf(o1));
                        listReversionDel.add(o2);
                        listPosDel.add(listNormal.indexOf(o2));
                    }
                } else if (!o1.getIssue().equalsIgnoreCase(o2.getIssue())
                        && o1.getPath().equalsIgnoreCase(o2.getPath())
                        && !o1.getRevision().equalsIgnoreCase(o2.getRevision())) {
                    boolean isDelDuplicate = false;
                    boolean isAddDuplicate = false;
                    for (int n : listPosDel) {
                        if (n == listNormal.indexOf(o2)) {
                            isDelDuplicate = true;
                            break;
                        }
                    }
                    for (int n : listPosAdd) {
                        if (n == listNormal.indexOf(o2)) {
                            isAddDuplicate = true;
                            break;
                        }
                    }
                    if (!isDelDuplicate) {
                        listDel.add(o2);
                        listPosDel.add(listNormal.indexOf(o2));
                    }
                    if (!isAddDuplicate) {
                        listPosAdd.add(listNormal.indexOf(o2));
                    }
                }
            }
        }

        for (int pos : listPosAdd) {
            LOG.info(":::::::::::::::::: posAdd = " + pos);
            listDiff.add(listNormal.get(pos));
        }
        for (int pos : listPosDel) {
            LOG.info(":::::::::::::::::: posDel = " + pos);
        }

        LOG.info(":::::::::::::::::::: listNormal.size() = " + listNormal.size());

        listNormal.removeAll(listDel);
        listNormal.removeAll(listReversionDel);
        listDiff.removeAll(listReversionDel);

        Collections.sort(listNormal, new Comparator<Tag>() {
            @Override
            public int compare(Tag o1, Tag o2) {
                return o1.getPath().compareTo(o2.getPath());
            }
        });
        normalRender = new TagMonitorNormalMainRenderer(chkAll, gridTagNormal);
        generateRenderer(gridTagNormal, normalRender, listNormal);

        Collections.sort(listDiff, new Comparator<Tag>() {
            @Override
            public int compare(Tag o1, Tag o2) {
                return o1.getPath().compareTo(o2.getPath());
            }
        });
        diffRender = new TagMonitorDiffMainRenderer();
        generateRenderer(gridDiffTag, diffRender, listDiff);

        errorRender = new TagMonitorErrorMainRenderer(chkAllError, gridErrorTag);
        generateRenderer(gridErrorTag, errorRender, listError);

        if (listError.size() > 0) {
            divError.setVisible(true);
        } else {
            divError.setVisible(false);
        }

        lbTotalNormal.setValue(String.valueOf(listNormal.size()));
        lbTotalDifference.setValue(String.valueOf(listDiff.size()));
        lbTotalError.setValue(String.valueOf(listError.size()));
    }

    private Boolean validateTag(String[] tag,
            String inputResolveTagName,
            Tag tagObject,
            int numType) throws UnsupportedEncodingException {

        String inputRevision = tagObject.getRevision();
        String inputIssue = tagObject.getIssue();
        String inputAuthor = tagObject.getUser().getUsername();

        if (tag == null || inputResolveTagName == null || inputIssue == null || inputAuthor == null || inputRevision == null) {
            tagObject.setDescription(ResourceUtil.getLabel("default.alert.message.invalid.missing", locale));
            return Boolean.FALSE;
        }

        String resolveVersion = null;
        String revision = null;
        String issue = null;
        String author = null;
        int idx = 0;
        for (String s : tag) {
            if (s.length() > numType) {
                if (revision != null
                        && resolveVersion != null
                        && author != null) {
                    break;
                }
                if (s.substring(0, 8).equals("revision")
                        && revision == null) {
                    if (rdoTagType.getSelectedItem().getValue().equals(TAG_TYPE_HOTFIX)) {
                        String revisionTemp = s.substring(9, s.length());
                        if (revisionTemp.trim().replace(".", ",").split(",").length == 4) {
                            revision = s.substring(9, s.length());
                            issue = tag[idx + 2];
                        }
                    } else {
                        revision = s.substring(9, s.length());
                        issue = tag[idx + 2];
                    }
                }
                if (s.substring(0, 8).equals("revision")
                        && revision != null
                        && author == null) {
                    String version = s.substring(9, s.length());
                    if (version.trim().equals(inputRevision)) {
                        author = tag[idx + 1].substring(tag[idx + 1].indexOf("author: ") + "author: ".length(),
                                tag[idx + 1].indexOf("state:") - 3);
                    }
                }
                if (s.indexOf(inputResolveTagName + ":") == 1
                        && resolveVersion == null) {
                    resolveVersion = s.substring((inputResolveTagName + ": ").length(), s.length());
                }
            }
            ++idx;
        }

        LOG.info("::::::::::::: resolveVersion = " + resolveVersion);
        LOG.info("::::::::::::: revision = " + revision);
        LOG.info("::::::::::::: author = " + author);
        LOG.info("::::::::::::: issue = " + issue);

        tagObject.setVersion(resolveVersion == null ? "New File" : resolveVersion);

        if (issue == null || revision == null) {
            return Boolean.FALSE;
        }

        revision = revision.trim();
//        issue = issue.trim();

//        if (!inputIssue.trim().equals(issue.trim())) {
//            tagObject.setDescription("Issue ที่ Commit ไม่ตรงกับ Issue ส่งไฟล์มา");
//            return Boolean.FALSE;
//        }

        if (!revision.equals(inputRevision)) {
            tagObject.setIsLasted(Boolean.FALSE);
        }

        if ((resolveVersion != null
                && resolveVersion.trim().equals(containReversion(inputRevision, resolveVersion.trim(), Boolean.TRUE)))) {
            tagObject.setDescription(ResourceUtil.getLabel("tag.description.invalid.less", locale));
            return Boolean.FALSE;
        }

        if (inputRevision.equals(containReversion(inputRevision, revision, Boolean.TRUE))) {
            tagObject.setDescription(ResourceUtil.getLabel("tag.description.invalid.more", locale));
            return Boolean.FALSE;
        }

        if (author != null && !author.trim().equals(inputAuthor.trim())) {
            tagObject.setDescription(ResourceUtil.getLabel("tag.description.invalid.commit", locale));
            return Boolean.FALSE;
        }

        if (resolveVersion != null
                && containReversion(inputRevision, resolveVersion.trim(), Boolean.FALSE) == null) {

            Boolean isNow = Boolean.FALSE;
            Boolean isValidate = Boolean.TRUE;
            Boolean isValidateCount = Boolean.TRUE;
            Boolean isEnd = Boolean.FALSE;
            String authorValidate = "";
            String revisionValidate = "";
            int count = 0;
            while (!isEnd) {
                StringBuilder sb = new StringBuilder();
                sb.append("cvs -d :pserver:").append((String) cbbCVSName.getSelectedItem().getValue()).append("@").append(GenerateScriptUtil.IP_CVS_SERVER_PATH).append(" log ").append(tagObject.getPath());

                LOG.info(":::::::::::::::::::::::: sb = " + sb.toString());

                ProcessUbuntu process = new ProcessUbuntu(cbbHeader.getText(), sb);
                process.process("chmod 777 " + cbbHeader.getText() + "/" + ProcessUbuntu.TEMP_SCRIPT_FILENAME);
                process.process();

                String[] tagValidate = process.getOutputString().split("\n");
                idx = 0;
                for (String s : tagValidate) {
                    if (count > 15 || (!isNow && idx == tagValidate.length - 1)) {
                        isValidateCount = Boolean.FALSE;
                        break;
                    }
                    if (s.length() > 10) {
                        if (s.substring(0, 8).equals("revision")
                                && s.substring(9, s.length()).trim().equals(inputRevision.trim())) {
                            isNow = Boolean.TRUE;
                            ++count;
                        }
                        if (s.substring(0, 8).equals("revision")
                                && isNow) {
                            authorValidate = tagValidate[idx + 1].substring(tagValidate[idx + 1].indexOf("author: ") + "author: ".length(),
                                    tagValidate[idx + 1].indexOf("state:") - 3);

                            revisionValidate = s.substring(9, s.length()).trim();

                            LOG.info("::::::::::::::::::::::: authorValidate = " + authorValidate);
                            LOG.info("::::::::::::::::::::::: revisionValidate = " + revisionValidate);

                            if (revisionValidate.equals(resolveVersion.trim())) {
                                isEnd = Boolean.TRUE;
                                break;
                            }

                            if (!authorValidate.trim().equals(tagObject.getUser().getUsername().trim())) {
                                if (((String) rdoTagType.getSelectedItem().getValue()).equals(TAG_TYPE_HOTFIX)) {
                                    if (revisionValidate.trim().replace(".", ",").split(",").length == 4) {
                                        isValidate = Boolean.FALSE;
                                        isEnd = Boolean.TRUE;
                                        break;
                                    }
                                } else if (((String) rdoTagType.getSelectedItem().getValue()).equals(TAG_TYPE_RELEASE)) {
                                    if (revisionValidate.trim().replace(".", ",").split(",").length == 2) {
                                        isValidate = Boolean.FALSE;
                                        isEnd = Boolean.TRUE;
                                        break;
                                    }
                                }
                            }
                            ++count;
                        }
                        LOG.info(":::::::::::::::::::::::::::: count = " + count);
                    }
                    ++idx;
                }
                if (!isValidateCount) {
                    break;
                }
            }

            if (!isValidateCount) {
                tagObject.setDescription("Revision ที่ใส่เข้ามาไม่ถูกต้อง");
                return Boolean.FALSE;
            }
            
            // Check jump version
//            if (!isValidate) {
//                tagObject.setDescription("Version กระโดด ณ version ที่ " + revisionValidate + " ผู้ commit คือ " + authorValidate + " กรุณาตรวจสอบ");
//                return Boolean.FALSE;
//            }
        }

        return Boolean.TRUE;
    }

    private String containReversion(String o1, String o2, Boolean isMore) {

        String[] reversion1 = o1.replace(".", ",").split(",");
        String[] reversion2 = o2.replace(".", ",").split(",");

        if (reversion1.length != reversion2.length) {
            return null;
        }

        LOG.info("::::::::::::::::::: reversion1.length = " + Arrays.toString(reversion1));
        LOG.info("::::::::::::::::::: reversion1.length = " + Arrays.toString(reversion2));

        for (int i = 0; i < reversion1.length; i++) {
            Integer num1 = Integer.parseInt(reversion1[i]);
            Integer num2 = Integer.parseInt(reversion2[i]);

            LOG.info("::::::::::::::::::: num1 [" + i + "] = " + num1);
            LOG.info("::::::::::::::::::: num2 [" + i + "] = " + num2);

            if (isMore) {
                if (num1 > num2) {
                    return o1;
                }
                if (num1 < num2) {
                    return o2;
                }
            } else {

                if (num1 - 1 == num2) {
                    return o1;
                }
                if (num2 - 1 == num1) {
                    return o2;
                }
            }
        }
        return null;
    }

    private void generateSettingFile() {
        List<String> allSetting = TextFileReaderUtil.read(FileAttribute.SETTING_TAG_MONITOR_FILE);
        tagName = new ArrayList<String>();
        header = new ArrayList<String>();
        cvsName = new ArrayList<String>();
        lastedTagName = new ArrayList<String>();

        if (!allSetting.isEmpty()) {
            for (String s : allSetting) {
                String[] setting = s.trim().split("=");
                if (setting[0].equals("TAG_NAME")) {
                    tagName.add(setting[1]);
                } else if (setting[0].equals("HEADER")) {
                    header.add(setting[1]);
                } else if (setting[0].equals("CVS_NAME")) {
                    cvsName.add(setting[1]);
                } else if (setting[0].equals("LASTED_TAG_NAME")) {
                    lastedTagName.add(setting[1]);
                }
            }
        }
    }

    private void appendSettingFile() {

        if (!tagName.contains(cbbTagName.getText())
                && !StringUtils.isEmpty(cbbTagName.getText())) {
            FileUtil.appandText(FileAttribute.SETTING_TAG_MONITOR_FILE, "TAG_NAME=" + (cbbTagName.getText()));
        }
        System.out.println("tagName = " + tagName.contains(cbbTagName.getText()));
        System.out.println("cbbTagName = " + cbbTagName.getText());

        if (!header.contains(cbbHeader.getText())
                && !StringUtils.isEmpty(cbbHeader.getText())) {
            FileUtil.appandText(FileAttribute.SETTING_TAG_MONITOR_FILE, "HEADER=" + (cbbHeader.getText()).trim());
        }
        System.out.println("header = " + header.contains(cbbHeader.getText()));
        System.out.println("cbbHeader = " + cbbHeader.getText());

        if (!cvsName.contains(cbbCVSName.getText())
                && !StringUtils.isEmpty(cbbCVSName.getText())) {
            FileUtil.appandText(FileAttribute.SETTING_TAG_MONITOR_FILE, "CVS_NAME=" + cbbCVSName.getText());
        }
        System.out.println("cvsName = " + cvsName.contains(cbbCVSName.getText()));
        System.out.println("cbbCVSName = " + cbbCVSName.getText());

        if (!lastedTagName.contains(cbbLastedTagName.getText())
                && !StringUtils.isEmpty(cbbLastedTagName.getText())) {
            FileUtil.appandText(FileAttribute.SETTING_TAG_MONITOR_FILE, "LASTED_TAG_NAME=" + cbbLastedTagName.getText());
        }
        System.out.println("lastedTagName = " + lastedTagName.contains(cbbLastedTagName.getText()));
        System.out.println("cbbCVSName = " + cbbLastedTagName.getText());

        initialCombobox();
    }

    private void initialCombobox() {

        File file = new File(FileAttribute.SETTING_TAG_MONITOR_FILE);
        LOG.info(file.getAbsolutePath());

        if (!file.exists()) {
            FileUtil.createFile(FileAttribute.SETTING_TAG_MONITOR_FILE, new StringBuilder(""));
        }

        generateSettingFile();

        Collections.reverse(tagName);
        ComboboxUtil.buildCombobox(cbbTagName, tagName, cbbTagName.getText());

        Collections.reverse(header);
        ComboboxUtil.buildCombobox(cbbHeader, header, cbbHeader.getText());

        Collections.reverse(cvsName);
        ComboboxUtil.buildCombobox(cbbCVSName, cvsName, cbbCVSName.getText());

        Collections.reverse(lastedTagName);
        ComboboxUtil.buildCombobox(cbbLastedTagName, lastedTagName, cbbLastedTagName.getText());
    }

    private void generateRenderer(Grid grid, RowRenderer renderer, List model) {
        grid.setRowRenderer(renderer);
        grid.setModel(new ListModelList<Tag>(model));
    }

    private class GenerateTagScript implements EventListener {

        @Override
        public void onEvent(Event event) throws Exception {
            appendSettingFile();

            String filename = cbbHeader.getText() + "/" + ProcessUbuntu.TEMP_SCRIPT_FILENAME;

            if (!validate()) {
                return;
            }

            List<Tag> listTag = new ArrayList<Tag>();
            for (Object o : normalRender.selectTemplateList) {
                Tag tag = (Tag) o;
                listTag.add(tag);
            }
            for (Object o : diffRender.getObjectSelect()) {
                Tag tag = (Tag) o;
                listTag.add(tag);
            }
            for (Object o : errorRender.selectTemplateList) {
                Tag tag = (Tag) o;
                listTag.add(tag);
            }
            GenerateScriptUtil.generate(listTag, cbbTagName.getText(), cbbCVSName.getText(), filename);

            List<String> script = TextFileReaderUtil.read(filename);
            LOG.info("::::::::::::::::::::::::: script.size() = " + script.size());

            Map map = new HashMap<String, Object>();
            map.put(PopupCtrl.EXECUTION_SCRIPT, script);
            map.put(PopupCtrl.EXECUTION_SCRIPT_FILENAME, filename);
            map.put(PopupCtrl.EXECUTION_SCRIPT_FILEPATH, cbbHeader.getText());
            Component comp = Executions.createComponents(FROM_POPUP_TEMPLATE, null, map);

            if (comp instanceof Window) {
                Window win = (Window) comp;
                win.setTitle(ProcessUbuntu.TEMP_SCRIPT_FILENAME);
                win.setPosition("0");
                win.setWidth("98%");
                win.doModal();
            }
        }
    }

    private class GenerateRollbackTagScript implements EventListener {

        @Override
        public void onEvent(Event event) throws Exception {
            appendSettingFile();

            String filename = cbbHeader.getText() + "/" + ProcessUbuntu.TEMP_SCRIPT_FILENAME;

            if (!validate()) {
                return;
            }

            List<Tag> listTag = new ArrayList<Tag>();
            for (Object o : normalRender.selectTemplateList) {
                Tag tag = (Tag) o;
                listTag.add(tag);
            }
            for (Object o : diffRender.getObjectSelect()) {
                Tag tag = (Tag) o;
                listTag.add(tag);
            }
            for (Object o : errorRender.selectTemplateList) {
                Tag tag = (Tag) o;
                listTag.add(tag);
            }
            GenerateScriptUtil.generateRollback(listTag, cbbTagName.getText(), cbbCVSName.getText(), filename);

            List<String> script = TextFileReaderUtil.read(filename);
            LOG.info("::::::::::::::::::::::::: script.size() = " + script.size());

            Map map = new HashMap<String, Object>();
            map.put(PopupCtrl.EXECUTION_SCRIPT, script);
            map.put(PopupCtrl.EXECUTION_SCRIPT_FILENAME, filename);
            map.put(PopupCtrl.EXECUTION_SCRIPT_FILEPATH, cbbHeader.getText());
            Component comp = Executions.createComponents(FROM_POPUP_TEMPLATE, null, map);

            if (comp instanceof Window) {
                Window win = (Window) comp;
                win.setTitle(ProcessUbuntu.TEMP_SCRIPT_FILENAME);
                win.setPosition("0");
                win.setWidth("98%");
                win.doModal();
            }
        }
    }

    private Boolean validate() {

        ValidateManager vm = new ValidateManager();

        vm.add(ValidateUtil.requireField(cbbTagName));
        vm.add(ValidateUtil.requireField(cbbHeader));
        vm.add(ValidateUtil.requireField(cbbCVSName));
        vm.add(ValidateUtil.requireField(cbbLastedTagName));

        if (!vm.getValue()) {
            AlertMessages.alertMessage(vm.getMessageTemplate());
            return Boolean.FALSE;
        }

        return Boolean.TRUE;
    }
}
